﻿using StackExchange.Redis;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.WebSockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;

namespace Drive.LiveExcelHost
{
    public class WebSocketSession
    {
        public List<MessageForThrottle> recentSendMessages;
        public CancellationToken cancellationToken;
        internal bool isAgentSession;

        public WebSocketSession(WebSocket webSocket, long visitorId, string sid, List<MessageForThrottle> lists, CancellationToken cancellationToken)
        {
            this.WebSocket = webSocket;
            this.VisitorId = visitorId;
            this.SessionId = sid;
            this.CreateTime = DateTime.Now;
            this.UserNameFunc = (uid) => RedisUserStore.GetNickName(uid);
            this.recentSendMessages = lists;
            this.cancellationToken = cancellationToken;
        }

        public WebSocket WebSocket { get; set; }
        public DateTime CreateTime { get; set; }
        public Func<long, string> UserNameFunc { get; }

        public string UserName
        {
            get
            {
                return UserNameFunc(this.VisitorId);
            }
        }
        public string SessionId { get; }
        public bool IsReady { get; internal set; }
        public bool HandshakeStarted { get; set; }

        public bool HandshakeCompleted { get; set; }
        public bool IsSendWelcome { get; internal set; }

        public ChatBuddy GetBuddy()
        {
            return new ChatBuddy
            {
                NickName = this.UserName,
                SessionId = this.SessionId,
                VisitorId = this.VisitorId
            };
        }
        public long VisitorId { get; internal set; }

        public string RedisChannel
        {
            get
            {
                return (this.isAgentSession ? "agent_" : "visitor_") + this.VisitorId;
            }
        }

        public bool IsSendTooFrenquncy()
        {
            if (recentSendMessages.Count > 20)
            {
                recentSendMessages.RemoveAt(0);
            }
            var from = DateTime.Now.AddSeconds(-5);
            var count = this.recentSendMessages.Count(x => x.SendTime > from);
            if (count > 12)
            {
                return true;
            }
            from = DateTime.Now.AddSeconds(-2);
            count = this.recentSendMessages.Count(x => x.SendTime > from);
            if (count > 4)
            {
                return true;
            }

            return false;
        }

        /// <summary>
        /// 将消息推送到客户端。必须是chatMessage的Json格式
        /// </summary>
        /// <param name="channel"></param>
        /// <param name="message"></param>
        internal async void PushToClient(RedisChannel channel, RedisValue message)
        {
            var body = new string[] { "chat message", message };
            var toSend = TextUtil.TextToBytes($"42{ Newtonsoft.Json.JsonConvert.SerializeObject(body, Newtonsoft.Json.Formatting.None)}");
            if (this.WebSocket.State == WebSocketState.Open && this.HandshakeCompleted)
            {
                if (!this.cancellationToken.IsCancellationRequested)
                    try
                    {
                        await this.WebSocket.SendAsync(toSend, WebSocketMessageType.Text, true, CancellationToken.None);
                    }
                    catch { }
            }
        }
    }
}
